GraphSage Embeddings Guide

This guide will show how to create graph sage embeddings. GraphSage training and models does not work in the current neo4j training and link prediction pipeline.

Project A Graph

Project a graph for the pubmed articles. Include drug, disease, gene_protein foundational nodes. Include only the `has_extraction` pubmed article relationship to the foundational graph nodes. Include the `model2vec_embeddings` to be merged with the graph sage embeddings.

call gds.graph.project(
  'pubmed_graph',
  [
      'disease', 
      'drug',
      'gene_protein',
      'pubmed_document'
  ],
  {
    has_extraction: {orientation: 'UNDIRECTED', type:'*'},
    disease_disease: {orientation: 'UNDIRECTED', type:'*'},
    disease_protein: {orientation: 'UNDIRECTED', type:'*'},
    drug_protein: {orientation: 'UNDIRECTED', type:'*'},
    drug_drug: {orientation: 'UNDIRECTED', type:'*'},
    drug_effect: {orientation: 'UNDIRECTED', type:'*'},
    protein_protein: {orientation: 'UNDIRECTED', type:'*'},
    indication: {orientation: 'UNDIRECTED', type:'*'},
    contraindication: {orientation: 'UNDIRECTED', type:'*'}
  },
  {
    nodeProperties: ['model2vec_embeddings', 'node_idx', 'label_one_hot_encoding']
  }
)
yield
  graphName AS graph, nodeProjection, nodeCount AS nodes, relationshipCount AS rels
return
  graph, nodeProjection, nodes, rels;
          
Project a pubmed graph

Sample Graph For Training

Reduce the size of the training graph using https://neo4j.com/docs/graph-data-science/current/management-ops/graph-creation/sampling/rwr/[random walk with restarts]. We can use random walk to train on a subset of the total graph because graph sage is "inductive" meaning we can learn embeddings for new unseen nodes.

call gds.graph.sample.rwr('pubmed_sampled_graph', 'pubmed_graph', { samplingRatio: 0.35 })
yield nodeCount, relationshipCount
return nodeCount, relationshipCount;
          
Reduce graph size by sampling with random walks

Train Graph Embeddings

Train graph embeddings using GraphSage. Merges graph embeddings with the sentence embeddings in field `model2vec_embeddings`.

call gds.beta.graphSage.train(
  'pubmed_sampled_graph',
  {
      modelName: 'pubmed_graphsage_model',
      featureProperties: ['model2vec_embeddings', 'label_one_hot_encoding'],
      embeddingDimension: 512,
      aggregator: 'mean',
      epochs: 3,
      maxIterations: 15,
      learningRate: .075,
      batchSize: 128,
      searchDepth: 5,
      penaltyL2: .001,
      sampleSizes: [32, 12],
      activationFunction: 'relu',
      projectedFeatureDimension: 256
  }
)
yield trainMillis, configuration, modelInfo
return trainMillis, configuration, modelInfo;
          
Train graph embeddings using GraphSage

Write Graph Embeddings To A New Field

Write graph embeddings to new field.

call gds.beta.graphSage.mutate(
  'pubmed_graph',
  {
    mutateProperty: 'graphsage_embedding',
    modelName: 'pubmed_graphsage_model'
  }
) yield
  nodeCount,
  nodePropertiesWritten;
          
Write graph embeddings

Use Graph Embeddings To Do KNN Node Classification

Use graph embeddings to do KNN node classification. The classification will connect similar PubMed articles.

call gds.knn.filtered.write('pubmed_graph', {
  nodeProperties: [
    {
      graphsage_embedding: 'COSINE'
    }
  ],
  nodeLabels: ['pubmed_document'],
  topK: 6,
  sampleRate: 1.0,
  deltaThreshold: 0.001,
  similarityCutoff: .85,
  randomSeed: 75,
  concurrency: 1,
  writeProperty: 'graphsage_score',
  writeRelationshipType: 'similar_article'
})
yield similarityDistribution
return similarityDistribution.mean as meanSimilarity;
          
Use graph embeddings to do KNN node classification

Similar Articles

View similar articles

match p=(d1:pubmed_document)-[r:similar_article]-(d2:pubmed_document)
where r.graphsage_score > .5
return p;
          
view similar articles

Clean Up

Delete graph, models and pipeline.

// delete article knn links
match (d1:pubmed_document)-[r:similar_article]-(d2:pubmed_document)
delete r;

// drop model
call gds.model.drop('pubmed_graphsage_model');

// drop graphs
call gds.graph.drop('pubmed_graph');
call gds.graph.drop('pubmed_sampled_graph');
          
Clean up